Goals
Load Packages
import gzip
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
import Redfin Metro Area Dataset. Contains Market Data since 2013
redfin_df = pd.read_csv(r"C:\Users\wilke\Downloads\redfin_metro_market_tracker.tsv000.gz",
compression='gzip',sep = '\t',header = 0,quotechar='"')
# get only Ohio records
oh_bool = []
for i in redfin_df['parent_metro_region']:
bool = 'OH' in i
oh_bool.append(bool)
oh_metrics = redfin_df[oh_bool]
oh_metrics.sort_values(['parent_metro_region','period_begin'])
| period_begin | period_end | period_duration | region_type | region_type_id | table_id | is_seasonally_adjusted | region | city | state | ... | sold_above_list_yoy | price_drops | price_drops_mom | price_drops_yoy | off_market_in_two_weeks | off_market_in_two_weeks_mom | off_market_in_two_weeks_yoy | parent_metro_region | parent_metro_region_metro_code | last_updated | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 13072 | 2012-01-01 | 2012-01-31 | 30 | metro | -2 | 10420 | f | Akron, OH metro area | NaN | NaN | ... | -0.031343 | NaN | NaN | NaN | 0.032086 | -0.017707 | 0.021275 | Akron, OH | 10420 | 2023-06-12 18:59:53 |
| 155928 | 2012-01-01 | 2012-01-31 | 30 | metro | -2 | 10420 | f | Akron, OH metro area | NaN | NaN | ... | -0.125000 | NaN | NaN | NaN | 0.000000 | 0.000000 | 0.000000 | Akron, OH | 10420 | 2023-06-12 18:59:53 |
| 189842 | 2012-01-01 | 2012-01-31 | 30 | metro | -2 | 10420 | f | Akron, OH metro area | NaN | NaN | ... | 0.070000 | NaN | NaN | NaN | 0.000000 | -0.071429 | 0.000000 | Akron, OH | 10420 | 2023-06-12 18:59:53 |
| 246828 | 2012-01-01 | 2012-01-31 | 30 | metro | -2 | 10420 | f | Akron, OH metro area | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | Akron, OH | 10420 | 2023-06-12 18:59:53 |
| 330225 | 2012-01-01 | 2012-01-31 | 30 | metro | -2 | 10420 | f | Akron, OH metro area | NaN | NaN | ... | -0.035880 | NaN | NaN | NaN | 0.036364 | -0.014095 | 0.024388 | Akron, OH | 10420 | 2023-06-12 18:59:53 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 213821 | 2023-04-01 | 2023-04-30 | 30 | metro | -2 | 49780 | f | Zanesville, OH metro area | NaN | NaN | ... | -0.189678 | 0.223881 | 0.018752 | 0.118617 | 0.347222 | 0.019353 | 0.049925 | Zanesville, OH | 49780 | 2023-06-12 18:59:53 |
| 78549 | 2023-05-01 | 2023-05-31 | 30 | metro | -2 | 49780 | f | Zanesville, OH metro area | NaN | NaN | ... | -0.086996 | 0.246753 | 0.039857 | 0.045570 | 0.400000 | 0.062162 | 0.034146 | Zanesville, OH | 49780 | 2023-06-12 18:59:53 |
| 154272 | 2023-05-01 | 2023-05-31 | 30 | metro | -2 | 49780 | f | Zanesville, OH metro area | NaN | NaN | ... | 0.000000 | 0.200000 | NaN | NaN | 0.666667 | 0.666667 | 0.666667 | Zanesville, OH | 49780 | 2023-06-12 18:59:53 |
| 312699 | 2023-05-01 | 2023-05-31 | 30 | metro | -2 | 49780 | f | Zanesville, OH metro area | NaN | NaN | ... | -0.074074 | 0.244755 | 0.020875 | 0.032255 | 0.381579 | 0.034357 | 0.027149 | Zanesville, OH | 49780 | 2023-06-12 18:59:53 |
| 317645 | 2023-05-01 | 2023-05-31 | 30 | metro | -2 | 49780 | f | Zanesville, OH metro area | NaN | NaN | ... | -1.000000 | 0.500000 | NaN | NaN | 1.000000 | NaN | 0.000000 | Zanesville, OH | 49780 | 2023-06-12 18:59:53 |
18561 rows × 58 columns
#All features in dataset
oh_metrics.columns
Index(['period_begin', 'period_end', 'period_duration', 'region_type',
'region_type_id', 'table_id', 'is_seasonally_adjusted', 'region',
'city', 'state', 'state_code', 'property_type', 'property_type_id',
'median_sale_price', 'median_sale_price_mom', 'median_sale_price_yoy',
'median_list_price', 'median_list_price_mom', 'median_list_price_yoy',
'median_ppsf', 'median_ppsf_mom', 'median_ppsf_yoy', 'median_list_ppsf',
'median_list_ppsf_mom', 'median_list_ppsf_yoy', 'homes_sold',
'homes_sold_mom', 'homes_sold_yoy', 'pending_sales',
'pending_sales_mom', 'pending_sales_yoy', 'new_listings',
'new_listings_mom', 'new_listings_yoy', 'inventory', 'inventory_mom',
'inventory_yoy', 'months_of_supply', 'months_of_supply_mom',
'months_of_supply_yoy', 'median_dom', 'median_dom_mom',
'median_dom_yoy', 'avg_sale_to_list', 'avg_sale_to_list_mom',
'avg_sale_to_list_yoy', 'sold_above_list', 'sold_above_list_mom',
'sold_above_list_yoy', 'price_drops', 'price_drops_mom',
'price_drops_yoy', 'off_market_in_two_weeks',
'off_market_in_two_weeks_mom', 'off_market_in_two_weeks_yoy',
'parent_metro_region', 'parent_metro_region_metro_code',
'last_updated'],
dtype='object')
Heatmap to get a look at correlated variables
plt.figure(figsize = (20,20))
sns.heatmap(oh_metrics.corr())
C:\Users\wilke\AppData\Local\Temp\ipykernel_47604\1925643702.py:2: FutureWarning: The default value of numeric_only in DataFrame.corr is deprecated. In a future version, it will default to False. Select only valid columns or specify the value of numeric_only to silence this warning. sns.heatmap(oh_metrics.corr())
<Axes: >
Histogram to visualize the distributions of all features
metrics_df = oh_metrics[[
'period_begin',
'parent_metro_region',
'property_type',
'median_list_price',
'median_sale_price',
'median_sale_price_mom',
'median_sale_price_yoy',
'months_of_supply',
'months_of_supply_mom',
'months_of_supply_yoy',
'homes_sold',
'homes_sold_mom',
'homes_sold_yoy',
'median_list_ppsf',
'median_list_ppsf_mom',
'median_list_ppsf_yoy',
'inventory',
'inventory_mom',
'inventory_yoy',
'avg_sale_to_list',
'sold_above_list',
'sold_above_list_mom',
'sold_above_list_yoy',
'off_market_in_two_weeks',
'price_drops',
'pending_sales',
'pending_sales_mom',
'pending_sales_yoy'
]]
#Visualize a histogram of all metrics to see distributions
ind = 1
plt.figure(figsize=(40,40))
for i in metrics_df.columns:
plt.subplot(len(metrics_df.columns),2,ind)
plt.hist(metrics_df[i])
plt.title(i)
ind += 1
#Split dataset into dayton marekt
dayton_market = metrics_df[metrics_df['parent_metro_region'] == 'Dayton, OH']
dayton_townhouse = dayton_market[dayton_market['property_type'] == 'Townhouse'].sort_values('period_begin')
dayton_family_home = dayton_market[dayton_market['property_type'] == 'Single Family Residential'].sort_values('period_begin')
dayton_condo = dayton_market[dayton_market['property_type'] == 'Condo/Co-op'].sort_values('period_begin')
dayton_multi_family = dayton_market[dayton_market['property_type'] == 'Multi-Family (2-4 Unit)'].sort_values('period_begin')
dayton_residential = dayton_market[dayton_market['property_type'] == 'All Residential'].sort_values('period_begin')
metrics = [ 'median_sale_price',
'inventory',
'median_list_price',
'homes_sold',
'avg_sale_to_list',
'sold_above_list',
'homes_sold',
'median_list_ppsf',
'pending_sales',
'off_market_in_two_weeks',
'price_drops',
]
fig, ax = plt.subplots(11,1,sharex = True,figsize = (20,30))
fig.tight_layout(pad = 5)
ax = ax.flatten()
for ind,i in enumerate(metrics):
ax[ind].plot(dayton_townhouse['period_begin'],dayton_townhouse[i])
ax[ind].set_title(i)
ax[ind].set_xticklabels(dayton_townhouse['period_begin'],rotation = 90)
C:\Users\wilke\AppData\Local\Temp\ipykernel_42968\3672131972.py:25: UserWarning: FixedFormatter should only be used together with FixedLocator ax[ind].set_xticklabels(dayton_townhouse['period_begin'],rotation = 90)
metrics = [ 'median_sale_price',
'inventory',
'median_list_price',
'homes_sold',
'avg_sale_to_list',
'sold_above_list',
'homes_sold',
'median_list_ppsf',
'pending_sales',
'off_market_in_two_weeks',
'price_drops',
]
fig, ax = plt.subplots(11,1,sharex = True,figsize = (20,30))
fig.tight_layout(pad = 5)
ax = ax.flatten()
for ind,i in enumerate(metrics):
ax[ind].plot(dayton_family_home['period_begin'],dayton_family_home[i])
ax[ind].set_title(i)
ax[ind].set_xticklabels(dayton_family_home['period_begin'],rotation = 90)
C:\Users\wilke\AppData\Local\Temp\ipykernel_42968\4127881422.py:31: UserWarning: FixedFormatter should only be used together with FixedLocator ax[ind].set_xticklabels(dayton_family_home['period_begin'],rotation = 90)
metrics = [ 'median_sale_price',
'inventory',
'median_list_price',
'homes_sold',
'avg_sale_to_list',
'sold_above_list',
'homes_sold',
'median_list_ppsf',
'pending_sales',
'off_market_in_two_weeks',
'price_drops',
]
fig, ax = plt.subplots(11,1,sharex = True,figsize = (20,30))
fig.tight_layout(pad = 5)
ax = ax.flatten()
for ind,i in enumerate(metrics):
ax[ind].plot(dayton_condo['period_begin'],dayton_condo[i])
ax[ind].set_title(i)
ax[ind].set_xticklabels(dayton_condo['period_begin'],rotation = 90)
C:\Users\wilke\AppData\Local\Temp\ipykernel_42968\1762790433.py:25: UserWarning: FixedFormatter should only be used together with FixedLocator ax[ind].set_xticklabels(dayton_condo['period_begin'],rotation = 90)
metrics = [ 'median_sale_price',
'inventory',
'median_list_price',
'homes_sold',
'avg_sale_to_list',
'sold_above_list',
'homes_sold',
'median_list_ppsf',
'pending_sales',
'off_market_in_two_weeks',
'price_drops',
]
fig, ax = plt.subplots(11,1,sharex = True,figsize = (20,30))
fig.tight_layout(pad = 5)
ax = ax.flatten()
for ind,i in enumerate(metrics):
ax[ind].plot(dayton_multi_family['period_begin'],dayton_multi_family[i])
ax[ind].set_title(i)
ax[ind].set_xticklabels(dayton_multi_family['period_begin'],rotation = 90)
C:\Users\wilke\AppData\Local\Temp\ipykernel_42968\2919694956.py:25: UserWarning: FixedFormatter should only be used together with FixedLocator ax[ind].set_xticklabels(dayton_multi_family['period_begin'],rotation = 90)
metrics = [ 'median_sale_price',
'inventory',
'median_list_price',
'homes_sold',
'avg_sale_to_list',
'sold_above_list',
'homes_sold',
'median_list_ppsf',
'pending_sales',
'off_market_in_two_weeks',
'price_drops',
]
fig, ax = plt.subplots(11,1,sharex = True,figsize = (20,30))
fig.tight_layout(pad = 5)
ax = ax.flatten()
for ind,i in enumerate(metrics):
ax[ind].plot(dayton_residential['period_begin'],dayton_residential[i])
ax[ind].set_title(i)
ax[ind].set_xticklabels(dayton_residential['period_begin'],rotation = 90)
C:\Users\wilke\AppData\Local\Temp\ipykernel_42968\3061486996.py:25: UserWarning: FixedFormatter should only be used together with FixedLocator ax[ind].set_xticklabels(dayton_residential['period_begin'],rotation = 90)
Only going to look at residential and single-family as they follow more predictable trends
Month_over_month
metrics_mom = [ 'median_sale_price_mom',
'inventory_mom',
'homes_sold_mom',
'sold_above_list_mom',
'median_list_ppsf_mom',
'pending_sales_mom'
]
fig, ax = plt.subplots(6,1,sharex = True,figsize = (20,30))
fig.tight_layout(pad = 5)
ax = ax.flatten()
for ind,i in enumerate(metrics_mom):
ax[ind].plot(dayton_family_home['period_begin'],dayton_condo[i])
ax[ind].set_title(i)
ax[ind].set_xticklabels(dayton_family_home['period_begin'],rotation = 90)
C:\Users\wilke\AppData\Local\Temp\ipykernel_47604\759831397.py:20: UserWarning: FixedFormatter should only be used together with FixedLocator ax[ind].set_xticklabels(dayton_family_home['period_begin'],rotation = 90)
Month-Over-Month
metrics_mom = [ 'median_sale_price_mom',
'inventory_mom',
'homes_sold_mom',
'sold_above_list_mom',
'median_list_ppsf_mom',
'pending_sales_mom'
]
fig, ax = plt.subplots(6,1,sharex = True,figsize = (20,30))
fig.tight_layout(pad = 5)
ax = ax.flatten()
for ind,i in enumerate(metrics_mom):
ax[ind].plot(dayton_residential['period_begin'],dayton_residential[i])
ax[ind].set_title(i)
ax[ind].set_xticklabels(dayton_residential['period_begin'],rotation = 90)
C:\Users\wilke\AppData\Local\Temp\ipykernel_47604\1691309848.py:20: UserWarning: FixedFormatter should only be used together with FixedLocator ax[ind].set_xticklabels(dayton_residential['period_begin'],rotation = 90)
metrics_mom = [ 'median_sale_price_yoy',
'inventory_yoy',
'homes_sold_yoy',
'sold_above_list_yoy',
'median_list_ppsf_yoy',
'pending_sales_yoy'
]
fig, ax = plt.subplots(6,1,sharex = True,figsize = (20,30))
fig.tight_layout(pad = 5)
ax = ax.flatten()
for ind,i in enumerate(metrics_mom):
ax[ind].plot(dayton_family_home['period_begin'],dayton_condo[i])
ax[ind].set_title(i)
ax[ind].set_xticklabels(dayton_family_home['period_begin'],rotation = 90)
C:\Users\wilke\AppData\Local\Temp\ipykernel_47604\2833583520.py:20: UserWarning: FixedFormatter should only be used together with FixedLocator ax[ind].set_xticklabels(dayton_family_home['period_begin'],rotation = 90)
Year-Over-Year
metrics_mom = [ 'median_sale_price_yoy',
'inventory_yoy',
'homes_sold_yoy',
'sold_above_list_yoy',
'median_list_ppsf_yoy',
'pending_sales_yoy'
]
fig, ax = plt.subplots(6,1,sharex = True,figsize = (20,30))
fig.tight_layout(pad = 5)
ax = ax.flatten()
for ind,i in enumerate(metrics_mom):
ax[ind].plot(dayton_residential['period_begin'],dayton_residential[i])
ax[ind].set_title(i)
ax[ind].set_xticklabels(dayton_residential['period_begin'],rotation = 90)
C:\Users\wilke\AppData\Local\Temp\ipykernel_47604\1910253905.py:20: UserWarning: FixedFormatter should only be used together with FixedLocator ax[ind].set_xticklabels(dayton_residential['period_begin'],rotation = 90)
Import dataset from FreddieMac
mortgage_df = pd.read_csv('mortgageData.csv',encoding= 'unicode_escape')
#convert to datetime
mortgage_df['Week'] = pd.to_datetime(mortgage_df['Week'])
#get only records that match with redfindata
mortgage_df = mortgage_df[mortgage_df['Week'] >= '2012-01-01']
#create columns to get dates groupable by month
warnings.filterwarnings("ignore")
mortgage_df['year'] = mortgage_df['Week'].dt.year
mortgage_df['month'] = mortgage_df['Week'].dt.month
mortgage_df['day'] = [1 for i in range(len(mortgage_df))]
mortgage_df
| Week | 30YrFRM | 30YrFees | 15YrFRM | 15YrFees | 51ARM | 51ARMFees | year | month | day | |
|---|---|---|---|---|---|---|---|---|---|---|
| 2127 | 2012-01-05 | 3.91 | 0.8 | 3.23 | 0.8 | 2.86 | 0.7 | 2012 | 1 | 1 |
| 2128 | 2012-01-12 | 3.89 | 0.7 | 3.16 | 0.8 | 2.82 | 0.7 | 2012 | 1 | 1 |
| 2129 | 2012-01-19 | 3.88 | 0.8 | 3.17 | 0.8 | 2.82 | 0.7 | 2012 | 1 | 1 |
| 2130 | 2012-01-26 | 3.98 | 0.7 | 3.24 | 0.8 | 2.85 | 0.7 | 2012 | 1 | 1 |
| 2131 | 2012-02-02 | 3.87 | 0.8 | 3.14 | 0.8 | 2.80 | 0.7 | 2012 | 2 | 1 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 2721 | 2023-05-25 | 6.57 | NaN | 5.97 | NaN | NaN | NaN | 2023 | 5 | 1 |
| 2722 | 2023-06-01 | 6.79 | NaN | 6.18 | NaN | NaN | NaN | 2023 | 6 | 1 |
| 2723 | 2023-06-08 | 6.71 | NaN | 6.07 | NaN | NaN | NaN | 2023 | 6 | 1 |
| 2724 | 2023-06-15 | 6.69 | NaN | 6.10 | NaN | NaN | NaN | 2023 | 6 | 1 |
| 2725 | 2023-06-22 | 6.67 | NaN | 6.03 | NaN | NaN | NaN | 2023 | 6 | 1 |
599 rows × 10 columns
#Create a new date column with days of the month all the same
mortgage_df['Date'] = pd.to_datetime({'year':mortgage_df['year'],
'month':mortgage_df['month'],
'day':mortgage_df['day']})
#drop original date columns
mortgage_clean_dates = mortgage_df.drop(['Week','year','month','day'],axis = 1)
#group by month in order to be able to join on redfin data
thirtyFRM = pd.DataFrame(mortgage_clean_dates.groupby('Date').agg(np.mean)['30YrFRM']).reset_index()
thirtyFRM = thirtyFRM[:-1]
dayton_residential.reset_index(inplace = True)
Join Redfin market data and Freddie Max mortgage data
dayton_residential_FRM = dayton_residential.merge(right = thirtyFRM['30YrFRM'], how = 'inner',right_index=True,left_index=True)
dayton_residential_FRM.columns
Index(['index', 'period_begin', 'parent_metro_region', 'property_type',
'median_list_price', 'median_sale_price', 'median_sale_price_mom',
'median_sale_price_yoy', 'months_of_supply', 'months_of_supply_mom',
'months_of_supply_yoy', 'homes_sold', 'homes_sold_mom',
'homes_sold_yoy', 'median_list_ppsf', 'median_list_ppsf_mom',
'median_list_ppsf_yoy', 'inventory', 'inventory_mom', 'inventory_yoy',
'avg_sale_to_list', 'sold_above_list', 'sold_above_list_mom',
'sold_above_list_yoy', 'off_market_in_two_weeks', 'price_drops',
'pending_sales', 'pending_sales_mom', 'pending_sales_yoy', '30YrFRM'],
dtype='object')
dayton_residential_FRM
| index | period_begin | property_type | parent_metro_region | median_sale_price | median_sale_price_mom | median_sale_price_yoy | median_list_price | median_list_price_yoy | homes_sold | ... | avg_sale_to_list | sold_above_list | sold_above_list_mom | sold_above_list_yoy | off_market_in_two_weeks | price_drops | pending_sales | pending_sales_mom | pending_sales_yoy | 30YrFRM | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 155893 | 2012-01-01 | All Residential | Dayton, OH | 69900.0 | -0.115190 | -0.068000 | 80000.0 | -0.089875 | 455.0 | ... | 0.918299 | 0.105495 | -0.002525 | 0.012944 | 0.260450 | NaN | 311.0 | 0.187023 | 0.126812 | 3.9150 |
| 1 | 132602 | 2012-02-01 | All Residential | Dayton, OH | 75000.0 | 0.072961 | -0.025974 | 92000.0 | -0.023355 | 533.0 | ... | 0.934589 | 0.133208 | 0.027714 | 0.031759 | 0.305040 | NaN | 377.0 | 0.212219 | 0.455598 | 3.8900 |
| 2 | 120193 | 2012-03-01 | All Residential | Dayton, OH | 85000.0 | 0.133333 | 0.223022 | 110000.0 | 0.004566 | 725.0 | ... | 0.935872 | 0.097931 | -0.035277 | -0.043789 | 0.393814 | NaN | 485.0 | 0.286472 | 0.203474 | 3.9540 |
| 3 | 237560 | 2012-04-01 | All Residential | Dayton, OH | 97000.0 | 0.141176 | 0.197531 | 99900.0 | -0.074143 | 702.0 | ... | 0.942678 | 0.119658 | 0.021727 | 0.029028 | 0.329710 | NaN | 552.0 | 0.138144 | 0.157233 | 3.9100 |
| 4 | 336108 | 2012-05-01 | All Residential | Dayton, OH | 95570.0 | -0.014742 | 0.061889 | 107900.0 | 0.079011 | 840.0 | ... | 0.949053 | 0.120238 | 0.000580 | -0.014258 | 0.270796 | NaN | 565.0 | 0.023551 | 0.304850 | 3.7980 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 132 | 331695 | 2023-01-01 | All Residential | Dayton, OH | 180000.0 | 0.000000 | 0.094225 | 169900.0 | 0.000000 | 515.0 | ... | 0.970267 | 0.207767 | -0.020370 | -0.114142 | 0.429231 | 0.381927 | 650.0 | 0.116838 | -0.203431 | 6.2725 |
| 133 | 255251 | 2023-02-01 | All Residential | Dayton, OH | 180000.0 | 0.000000 | 0.033592 | 185500.0 | 0.031128 | 673.0 | ... | 0.973408 | 0.233284 | 0.025517 | -0.160159 | 0.503279 | 0.254593 | 610.0 | -0.061538 | -0.188830 | 6.2575 |
| 134 | 301717 | 2023-03-01 | All Residential | Dayton, OH | 185000.0 | 0.027778 | 0.054131 | 199900.0 | 0.000000 | 811.0 | ... | 0.983608 | 0.311961 | 0.078677 | -0.145648 | 0.571770 | 0.254919 | 836.0 | 0.370492 | -0.130073 | 6.5440 |
| 135 | 180461 | 2023-04-01 | All Residential | Dayton, OH | 200000.0 | 0.081081 | 0.000000 | 209900.0 | 0.105319 | 838.0 | ... | 0.993206 | 0.403341 | 0.091381 | -0.118170 | 0.558580 | 0.241220 | 845.0 | 0.010766 | -0.211018 | 6.3425 |
| 136 | 113081 | 2023-05-01 | All Residential | Dayton, OH | 212735.0 | 0.063675 | 0.037732 | 219900.0 | 0.072683 | 987.0 | ... | 0.998522 | 0.436677 | 0.033336 | -0.079396 | 0.540948 | 0.268335 | 928.0 | 0.098225 | -0.247974 | 6.4250 |
137 rows × 31 columns
sales_FRM = dayton_residential_FRM[['30YrFRM','median_sale_price']]
inventory_FRM = dayton_residential_FRM[['30YrFRM','inventory']]
plt.scatter(sales_FRM['median_sale_price'],sales_FRM['30YrFRM'])
plt.xlabel('Median Sale Price')
plt.ylabel('Mortgage Rate')
print(f'Correlation Coefficient: {sales_FRM.corr()}')
Correlation Coefficient: 30YrFRM median_sale_price 30YrFRM 1.000000 0.262442 median_sale_price 0.262442 1.000000
plt.scatter(inventory_FRM['inventory'],inventory_FRM['30YrFRM'])
plt.xlabel('Inventory')
plt.ylabel('Mortgage Rate')
print(f'Correlation Coefficient: {sales_FRM.corr()}')
Correlation Coefficient: 30YrFRM median_sale_price 30YrFRM 1.000000 0.262442 median_sale_price 0.262442 1.000000
metrics_mom = [ 'median_sale_price',
'inventory',
'30YrFRM'
]
fig, ax = plt.subplots(3,1,sharex = True,figsize = (20,30))
fig.tight_layout(pad = 5)
ax = ax.flatten()
for ind,i in enumerate(metrics_mom):
ax[ind].plot(dayton_residential_FRM['period_begin'],dayton_residential_FRM[i])
ax[ind].set_title(i)
ax[ind].set_xticklabels(dayton_residential_FRM['period_begin'],rotation = 90)
Questions about this